home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
vol6n19.arc
/
CTYPE.ASM
next >
Wrap
Assembly Source File
|
1987-08-21
|
23KB
|
564 lines
;CTYPE.COM for the IBM Personal Computer - 1987 by Jeff Prosise
bios_data segment at 40h
org 60h
cursor_mode dw ? ;cursor scan lines
org 63h
addr_6845 dw ? ;CRT Controller base address
org 87h
ega_info db ? ;EGA info byte
bios_data ends
;----------------------------------------------------------------------
code segment para public 'code'
assume cs:code,ds:code
org 100h
begin: jmp ctype
program db 'CTYPE 1.0 '
copyright db '(c) 1987 Ziff Communications Co.',1Ah
author db 'Jeff Prosise'
header db 'PC Magazine Cursor Definition Utility',0
subheader db 'CTYPE /',0
footer1 db '< Use arrow keys to navigate grid >',0,0
db 'ENTER : Select cursor and exit',0
db 'SPACEBAR : View cursor with text',0
footer2 db '< Press SPACEBAR to return >',0,0
db 'A single line of sample text',0
errmsg db 13,10,'Illegal parameters',13,10,'$'
adapter db 3 ;0=MDA, 1=CGA, 2=EGA, 3=VGA
points label byte
lpoints dw 8 ;scan lines per row (default=CGA)
rows db 24 ;number of rows (default=CGA, MDA)
columns db ? ;number of video columns
attr1 db 02h ;main video attribute
attr2 db 1Fh ;auxiliary video attribute
old_attr db 0
deltacol db 2 ;space between frame columns
startcol db ? ;first frame column
vpage db ? ;active video page
textrow db ? ;row where text footer begins
;-----------------------------------------------------------------------------
;CTYPE is the main procedure.
;-----------------------------------------------------------------------------
ctype proc near
;
;Find the current color of the screen for clearing later.
;
mov ah,15 ;get columns and page
int 10h
mov columns,ah ;save them
mov vpage,bh
mov ah,8 ;save old screen colors
int 10h
mov old_attr,ah
mov ax,bios_data ;point ES to BIOS data area
mov es,ax
assume es:bios_data
;
;Determine what type of video adapter is active, whether video is color
;or monochrome, and how many scan lines make up each character box.
;
mov ax,1A00h ;check for a VGA
int 10h
cmp al,1Ah ;is AL set to 1Ah?
jne check_ega ;no, then no VGA present
cmp bl,7 ;test for active VGA
jb check_ega
cmp bl,8
ja check_ega
call SetVideoParms ;determine rows and points
cmp bl,7 ;reset attributes if monochrome
je mono
jmp short checkparm ;done if video is color
check_ega: dec adapter ;assume this is an EGA
mov ah,12h ;video function 12h
mov bl,10h ;subfunction - return EGA info
int 10h
cmp bl,10h ;did BL return unchanged?
je no_ega ;yes, then no EGA
test ega_info,8 ;is the EGA currently active?
jnz no_ega ;no, then continue the check
call SetVideoParms ;determine rows and points
or bh,bh ;is BH zero?
jne mono ;no, then it's a mono system
jmp short checkparm ;yes, then it's color
no_ega: dec adapter ;assume this is a CGA
test addr_6845,40h ;is bit 6 of the CRTC address set?
jnz checkparm ;yes, then it's a CGA
mov points,14 ;no, then it's an MDA
dec adapter ;set ADAPTER to zero for MDA
mono: mov attr1,07h ;alter video parameters for mono
mov attr2,70h
;
;Check the command line for cursor definition parameters.
;
checkparm: push cs ;point ES to code segment
pop es
assume es:code
cld ;clear DF
mov di,82h ;point ES:DI to text of line
cmp byte ptr [di-2],2 ;at least 2 characters entered?
jb noparm ;no, then nothing was entered
mov cx,10 ;check for slash character
mov al,'/'
repne scasb
jcxz noparm ;branch if command line is empty
mov cx,[di] ;get 2 characters after slash
and cx,0DFDFh ;capitalize them
sub cx,4141h ;then normalize them
cmp ch,points ;see if they're in range
jae parm_error
cmp cl,points
jae parm_error
;
;Set the cursor and exit.
;
xchg ch,cl ;swap CH and CL
mov al,points ;calculate ending scan line
sub al,cl
dec al
cmp ch,al ;make sure parameters are legal
ja parm_error
mov cl,al ;transfer scan line to CL
call SetCursorMode ;set cursor shape
cursor_exit: mov ax,4C00h ;exit with ERRORLEVEL = 0
int 21h
;
;Command line parameters are out of range. Print error message and exit.
;
parm_error: mov ah,9 ;print error message
mov dx,offset errmsg
int 21h
mov ax,4C01h ;exit with ERRORLEVEL = 1
int 21h
;
;Create the cursor definition screen for interactive mode selection.
;
noparm:
; mov ah,15 ;get columns and page
; int 10h
; mov columns,ah ;save them
; mov vpage,bh
cmp columns,80 ;at least 80 columns displayed?
jae col80 ;yes, then branch
mov deltacol,1 ;no, then adjust for short display
col80: call ClearScreen ;clear the screen
mov ah,1 ;hide the cursor
mov ch,20h
int 10h
mov ax,0920h ;blank the screen header line
mov bl,attr2
mov bh,vpage
mov cl,columns
xor ch,ch
int 10h
mov si,offset header ;display screen header
xor dh,dh
mov dl,columns
sub dl,37
shr dl,1
call WriteString
call DrawFrame ;draw the cursor selection frame
mov ah,2 ;display 'CTYPE /XX' subheader
mov dh,2
mov dl,startcol
mov bl,attr1
mov si,offset subheader
call WriteString
;
;Position and display a 2-line underline cursor.
;
mov cl,points ;get number of scan lines
dec cl ;decrement it for ending line
mov ch,cl ;set starting line one higher
dec ch
jmp short display
;
;Enter a loop, polling the keyboard for keypresses.
;
getkey: mov ah,0 ;get a keypress
int 16h
or al,al ;extended code?
je excode ;yes, then branch
cmp al,32 ;SPACEBAR?
jne nospace
call ShowText ;show cursor with text
jmp short getkey ;return for more
nospace: cmp al,13 ;ENTER key?
jne getkey ;no, then ignore keypress
call ClearScreen ;clear screen and exit
jmp cursor_exit
excode: cmp ah,72 ;Up-arrow?
jne checklft
or ch,ch ;decrement starting scan line
jne ex1
mov ch,cl
jmp short display
ex1: dec ch
jmp short display
checklft: cmp ah,75 ;Left-arrow?
jne checkrt
inc cl ;increment ending scan line
cmp cl,points
jne display
mov cl,ch
jmp short display
checkrt: cmp ah,77 ;Right-arrow?
jne checkdn
cmp ch,cl ;decrement ending scan line
jne rt1
mov cl,points
dec cl
jmp short display
rt1: dec cl
jmp short display
checkdn: cmp ah,80 ;Down-arrow?
jne getkey ;no, then ignore the keypress
cmp ch,cl ;increment starting scan line
jne dn1
xor ch,ch
jmp short display
dn1: inc ch
display: call ShowParm ;display command line parameters
call LocateCursor ;reposition the cursor
call SetCursorMode ;then display it in its new form
jmp short getkey ;return to keyboard loop
ctype endp
;-----------------------------------------------------------------------------
;SetVideoParms retrieves and stores the number of rows displayed and the
;number of scan lines per character.
;-----------------------------------------------------------------------------
SetVideoParms proc near
push bx ;save BX
mov ax,1130h ;get scan line and row count
int 10h
mov rows,dl ;save them (rows - 1)
mov points,cl
pop bx ;restore BX
ret
SetVideoParms endp
;-----------------------------------------------------------------------------
;SetCursorMode sets the shape of the cursor.
;Entry: CH,CL - beginning and ending scan lines
;-----------------------------------------------------------------------------
SetCursorMode proc near
push cx ;save CX for screen location
cmp adapter,2 ;is an EGA active?
jne scm1 ;no, then branch
inc cl ;yes, then adjust ending line
cmp cl,points ;wrap around if necessary
jne scm0
xor cl,cl
scm0: cmp ch,cl ;should this be a block cursor?
jne scm1 ;no, then branch
mov cl,1Eh ;yes, then adjust ending scan line
scm1: push es ;save ES
mov ax,bios_data
mov es,ax
assume es:bios_data
mov dx,addr_6845 ;get CRT Controller address
mov cursor_mode,cx ;save definition in BIOS area
pop es ;restore ES
assume es:code
mov al,10 ;OUT CH and CL to cursor registers
out dx,al
inc dx
mov al,ch
out dx,al
dec dx
mov al,11
out dx,al
inc dx
mov al,cl
out dx,al
pop cx ;retrieve nominal cursor shape
ret
SetCursorMode endp
;-----------------------------------------------------------------------------
;ShowText displays the current cursor on a line of text.
;-----------------------------------------------------------------------------
endcol db ? ;ending column
ShowText proc near
push cx ;save cursor parameter
call ClearRegion ;clear lower part of screen
mov si,offset footer2 ;display new footer
mov cx,3
call DrawFooter
mov ah,2 ;home the cursor
dec dh
int 10h
mov endcol,dl ;calculate rightmost column
add endcol,27
input: mov ah,0 ;get a keystroke
int 16h
or al,al ;extended code?
je fkey ;yes, then branch
cmp al,32 ;SPACEBAR?
jne input ;no, then ignore it
call ClearRegion ;restore main footer
mov si,offset footer1
mov cx,4
call DrawFooter
pop cx ;restore cursor parameter
call LocateCursor ;restore cursor position
ret
fkey: cmp ah,75 ;Left-arrow?
jne fkey1
cmp dl,startcol ;at left end of line?
je input ;yes, then don't move
dec dl ;move one character left
fkey0: mov ah,2
mov bh,vpage
int 10h
jmp short input ;return for more
fkey1: cmp ah,77 ;Right-arrow?
jne input ;no, then ignore it
cmp dl,endcol ;at right end of line?
je input ;yes, then don't move
inc dl ;advance cursor
jmp short fkey0
ShowText endp
;-----------------------------------------------------------------------------
;LocateCursor positions the cursor inside the selection frame.
;Entry: CH,CL - starting and ending cursor scan lines
;-----------------------------------------------------------------------------
LocateCursor proc near
mov dh,ch ;calculate screen row from CH
add dh,4
mov dl,startcol ;calculate column from CL
add dl,2
mov al,deltacol
add dl,al
inc al
mov bl,points
sub bl,cl
dec bl
mul bl
add dl,al
mov bh,vpage ;set video page number
mov ah,2 ;position cursor
int 10h
ret
LocateCursor endp
;-----------------------------------------------------------------------------
;ShowParm updates the display of the current cursor's /XX parameters.
;Entry: CH,CL - starting and ending scan lines
;-----------------------------------------------------------------------------
ShowParm proc near
mov ah,2 ;position the cursor
mov bh,vpage
mov dh,2
mov dl,startcol
add dl,7
int 10h
mov ah,0Eh ;write first character
mov al,ch
add al,41h
int 10h
mov ah,0Eh ;write second character
mov al,points
sub al,cl
add al,40h
int 10h
ret
ShowParm endp
;-----------------------------------------------------------------------------
;DrawFrame draws the cursor definition frame.
;-----------------------------------------------------------------------------
numpoints dw ? ;counter for dots per line
;
DrawFrame proc near
mov al,points ;calculate length of top line
mov bl,deltacol
inc bl
mul bl
add ax,3
mov cx,ax ;transfer result to CX
mov bl,columns ;calculate starting column number
sub bl,al
shr bl,1
mov startcol,bl
mov ah,2 ;position cursor for top line
mov dh,3
mov dl,startcol
mov bh,vpage
int 10h
mov ax,0920h ;blank out the top line
mov bl,attr2
int 10h
mov cx,lpoints ;fill in text of top line
mov dh,3
mov dl,startcol
add dl,deltacol
add dl,2
mov al,'A'
drawloop1: mov bl,al
mov ah,2
int 10h
mov ah,0Eh
mov al,bl
int 10h
add dl,deltacol
inc dl
mov al,bl
inc al
loop drawloop1
mov cx,lpoints ;then blank the vertical leg
mov dh,4
mov dl,startcol
mov bl,attr2
drawloop2: push cx
mov ah,2
int 10h
mov ax,0920h
mov cl,deltacol
inc cl
xor ch,ch
int 10h
inc dh
pop cx
loop drawloop2
mov cx,lpoints ;fill in the dots and text
mov numpoints,cx
mov dh,4
mov dl,startcol
inc dl
mov al,'A'
drawloop3: push cx
mov bl,al
mov ah,2
int 10h
mov al,bl
mov ah,0Eh
int 10h
mov cx,numpoints ;fill one grid line
drawloop4: mov ah,2
add dl,deltacol
inc dl
int 10h
mov ax,0EF9h
int 10h
loop drawloop4
dec numpoints ;one less dot on next line
mov al,bl
inc al
inc dh
mov dl,startcol
inc dl
pop cx
loop drawloop3
mov textrow,dh ;store current row number
inc textrow
mov si,offset footer1 ;draw text footer
mov cx,4
call DrawFooter
ret
DrawFrame endp
;-----------------------------------------------------------------------------
;DrawFooter writes a block of text below the selection frame.
;Entry: CX - number of lines
;-----------------------------------------------------------------------------
DrawFooter proc near
mov dh,textrow ;initialize cursor position
mov dl,startcol
mov bl,attr1 ;set attribute
drawloop5: push cx ;enter loop
call WriteString ;write one line
inc dh ;advance cursor
mov dl,startcol
pop cx
loop drawloop5 ;loop until done
ret
DrawFooter endp
;-----------------------------------------------------------------------------
;WriteString writes an ASCIIZ text string to video memory.
;Entry: DS:SI - string address
; DH,DL - starting cursor address
; BL - attribute
;-----------------------------------------------------------------------------
WriteString proc near
mov ah,2 ;position cursor
mov bh,vpage
int 10h
lodsb ;get a byte
or al,al ;is it the delimiter?
je ws1 ;yes, then exit
mov ah,9 ;no, then display it
mov cx,1
int 10h
inc dl ;advance the cursor
jmp short WriteString ;loop until done
ws1: ret
WriteString endp
;-----------------------------------------------------------------------------
;ClearScreen clears the display and homes the cursor.
;-----------------------------------------------------------------------------
ClearScreen proc near
mov ah,2 ;home the cursor
xor dx,dx
mov bh,vpage
int 10h
xor cx,cx ;define upper right corner
clear1: mov dl,columns ;define lower right corner
dec dl
mov dh,rows
mov bh,old_attr
mov ax,0600h ;video function 6
int 10h ;clear region
ret
ClearScreen endp
;-----------------------------------------------------------------------------
;ClearRegion clears the lower portion of the display.
;-----------------------------------------------------------------------------
ClearRegion proc near
mov ch,textrow ;define upper left corner
xor cl,cl
jmp short clear1
ClearRegion endp
;
code ends
end begin